package com.szewec.ps.util.okhttp;

import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.szewec.ps.base.BaseApplication;
import com.szewec.ps.base.BaseUrl;
import com.szewec.ps.myview.toast.bamtoast.BamToast;
import com.szewec.ps.util.LogUtil;
import com.szewec.ps.util.NetWorkUtil;
import com.szewec.ps.util.PreferincesContext;
import com.szewec.ps.util.SharedPreferencesUtil;
import com.szewec.ps.util.StringUtils;
import com.szewec.ps.util.dialog.LoadingDialog;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.FormBody;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;

/**
 * OKHttp
 */

public class OkHttp {
    private static final String TAG = "OKhttpManager";
    private static OkHttpClient mClient;
    private volatile static OkHttp sManager;//防止多个线程同时访问
    private static String token;
    private static String projectId;
    private static Handler handler;

    static {
        mClient = new OkHttpClient.Builder()
                .connectTimeout(15, TimeUnit.SECONDS) //超时限制
                .readTimeout(15, TimeUnit.SECONDS)
                .writeTimeout(15, TimeUnit.SECONDS)
                .build();
        handler = new Handler();
        token = (String) SharedPreferencesUtil.getData(PreferincesContext.TOKEN, "");
        Log.i(TAG, "token is：" + token);
        projectId = (String) SharedPreferencesUtil.getData(PreferincesContext.PROJECT_ID, "");
    }

    public static OkHttpClient getClient() {
        return mClient;
    }

    //    定义要调用的接口
    public interface MyCallback {
        void onSuccess(String result);
    }

    public static void handleCallBack(Request request, Response response, MyCallback myCallback) {
        try {
            if (response != null) {
                LogUtil.i(TAG, "code:" + response.code());
                switch (response.code()) {
                    case 200:
                        if (response.body() != null) {
                            String result = response.body().string();
                            handler.post(() -> {
                                try {
                                    myCallback.onSuccess(result);
                                } catch (Exception e) {
                                    e.printStackTrace();
                                }
                            });
                        }
                        break;
                    case 401:
                        LogUtil.i(TAG, "401");
                        NetWorkUtil.updateToken(request, myCallback);
                        break;
//                    case 500:
//                        break;
                    default:
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void post(String url, Object jsonString, final MyCallback callBack) {
        updateHeader();
        if (jsonString == null) {
            return;
        }
        LogUtil.i(TAG, "url is:" + BaseUrl.base + url);

        String str = JSON.toJSONString(jsonString);

        RequestBody request_body = FormBody.create(MediaType.parse("application/json"), str);

        LogUtil.i(TAG, "param is:" + str);

        Request request = new Request.Builder().url(BaseUrl.base + url)
                .addHeader("x-project-id", projectId)
                .addHeader("authorization", token)
                .post(request_body)
                .build();
        mClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                BamToast.showText(BaseApplication.getContext(), "连接错误", false);
            }

            @Override
            public void onResponse(Call call, Response response) {
                handleCallBack(request, response, callBack);
            }
        });
    }

    public static void get(String url, Map<String, Object> params, LoadingDialog loadingDialog, final MyCallback callBack) {
        if (loadingDialog != null) {
            loadingDialog.show();
        }
        updateHeader();
        //处理参数
        if (params != null) {
            StringBuffer newUrl = params.size() > 0 ? new StringBuffer(url + "?") : new StringBuffer(url);
            for (HashMap.Entry<String, Object> entry : params.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                if (newUrl.indexOf("=") != -1) {
                    newUrl.append("&");
                }
                newUrl.append(key).append("=").append(value);
            }
            url = newUrl.toString();
        }
        LogUtil.i(TAG, "url:" + BaseUrl.base + url);
        // 非空键值对
        Request request = new Request.Builder().url(BaseUrl.base + url)
                .addHeader("x-project-id", projectId)
                .addHeader("authorization", token)
                .get()
                .build();//采用get方式提交
        mClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
                LogUtil.e(TAG, "网络错误!");
                new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        if (loadingDialog != null) {
                            loadingDialog.close();
                        }
                        BamToast.showText(BaseApplication.getContext(), "网络错误", false);
                    }
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                if (loadingDialog != null) {
                    loadingDialog.close();
                }
                handleCallBack(request, response, callBack);
            }
        });
    }

    public static void put(String url, Object jsonString, final MyCallback callBack) {
        updateHeader();
        if (jsonString == null) {
            return;
        }
        RequestBody request_body = FormBody.create(MediaType.parse("application/json"), JSON.toJSONString(jsonString, SerializerFeature.WriteMapNullValue));

        Request request = new Request.Builder().url(BaseUrl.base + url)
                .addHeader("x-project-id", projectId)
                .addHeader("authorization", token)
                .put(request_body)
                .build();
        LogUtil.i(TAG, "RUL:" + request.url().toString());
        LogUtil.i(TAG, "参数:" + JSON.toJSONString(jsonString));
        mClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                BamToast.showText(BaseApplication.getContext(), "连接错误", false);
            }

            @Override
            public void onResponse(Call call, Response response) {
                handleCallBack(request, response, callBack);
            }
        });
    }

    public static void delete(String url, final MyCallback callBack) {
        updateHeader();

        Request request = new Request.Builder().url(BaseUrl.base + url)
                .addHeader("x-project-id", projectId)
                .addHeader("authorization", token)
                .delete()
                .build();
        mClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                BamToast.showText(BaseApplication.getContext(), "连接错误", false);
            }

            @Override
            public void onResponse(Call call, Response response) {
                handleCallBack(request, response, callBack);
            }
        });
    }

    public static void postByForm(String url, Map<String, String> params, final MyCallback callBack) {
        FormBody.Builder form_builder = new FormBody.Builder();//表单对象包含以input开始的对象以html为主
        //非空键值对
        if (params != null && !params.isEmpty()) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                form_builder.add(entry.getKey(), entry.getValue());
            }
        }

        RequestBody request_body = form_builder.build();
        Request request = new Request.Builder().url(url).post(request_body)
                .build();//采用post方式提交
        mClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
                LogUtil.e(TAG, "网络错误!");
            }

            @Override
            public void onResponse(Call call, Response response) {
                handleCallBack(request, response, callBack);
            }
        });
    }

    public static void getWithoutBaseUrl(String url, final MyCallback callBack) {
        updateHeader();
        // 非空键值对
        Request request = new Request.Builder().url(url)
                .addHeader("authorization", token)
                .build();//采用get方式提交
        mClient.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
//                BamToast.showText(BaseApplication.getContext(),"连接错误",false);
                e.printStackTrace();
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                handleCallBack(request, response, callBack);
            }
        });
    }

    public static void updateHeader() {
        String localToken = (String) SharedPreferencesUtil.getData(PreferincesContext.TOKEN, "");
        token = StringUtils.isEmpty(localToken) ? "defaultToken" : localToken;
        System.out.println(token);
        String localProjectId = (String) SharedPreferencesUtil.getData(PreferincesContext.PROJECT_ID, "");
        projectId = StringUtils.isEmpty(localProjectId) ? "defaultProjectId" : localProjectId;
        System.out.println(projectId);
    }
}
